﻿using System;
using System.Globalization;

namespace DimensionsHelper.Common.Metadata.Script;

/// <summary>
///     表达式中的小数值。
/// </summary>
public class ExpressionDouble : ExpressionBasicType
{
    /// <summary>
    ///     表达式中的小数值。
    /// </summary>
    public ExpressionDouble(double value) : base(BasicTypes.Double)
    {
        Value = value;
    }

    /// <summary>
    ///     表达式小数对应的具体小数数值。
    /// </summary>
    public double Value { get; }

    public override object GetValue(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return Convert.ToInt32(Value);
            case BasicTypes.Double:
                return Value;
            case BasicTypes.String:
                return Value.ToString(CultureInfo.InvariantCulture);
            case BasicTypes.Boolean:
                return Convert.ToBoolean(Value);
            default:
                throw ThrowHelper.TypeConvertFailed("Double", type.ToString());
        }
    }

    public override ExpressionBasicType ConvertTo(BasicTypes type)
    {
        switch (type)
        {
            case BasicTypes.Integer:
                return new ExpressionInteger(Convert.ToInt32(Value));
            case BasicTypes.Double:
                return this;
            case BasicTypes.String:
                return new ExpressionString(Value.ToString(CultureInfo.InvariantCulture));
            case BasicTypes.Boolean:
                return new ExpressionBoolean(Value != 0);
            default:
                throw ThrowHelper.TypeConvertFailed("Double", type.ToString());
        }
    }

    public override bool CanImplicitlyConvert(BasicTypes type)
    {
        return type == BasicTypes.Double;
    }

    public override ExpressionBasicType Add(ExpressionBasicType expression)
    {
        return new ExpressionDouble(Value + (double)expression.GetValue(BasicTypes.Double));
    }

    public override ExpressionBasicType Subtract(ExpressionBasicType expression)
    {
        return new ExpressionDouble(Value - (double)expression.GetValue(BasicTypes.Double));
    }

    public override ExpressionBasicType Multiply(ExpressionBasicType expression)
    {
        return new ExpressionDouble(Value * (double)expression.GetValue(BasicTypes.Double));
    }

    public override ExpressionBasicType Divide(ExpressionBasicType expression)
    {
        return new ExpressionDouble(Value / (double)expression.GetValue(BasicTypes.Double));
    }

    public override ExpressionBasicType Modulo(ExpressionBasicType expression)
    {
        return new ExpressionDouble(Value % (double)expression.GetValue(BasicTypes.Double));
    }

    public override string ToString()
    {
        return Value.ToString(CultureInfo.InvariantCulture);
    }
}